#include "gtkmarshalers.h"
#include "gtksettingsprivate.h"
#include "gtktypebuiltins.h"
+#include "gtkcssstylepropertyprivate.h"
+#include "gtkcsssectionprivate.h"
/*
* CSS nodes are the backbone of the GtkStyleContext implementation and
gtk_css_node_get_style_provider (GtkCssNode *cssnode)
{
GtkStyleProviderPrivate *result;
-
+
result = gtk_css_node_get_style_provider_or_null (cssnode);
if (result)
return result;
return GTK_STYLE_PROVIDER_PRIVATE (_gtk_settings_get_style_cascade (gtk_settings_get_default (), 1));
}
+
+static void
+append_id (GtkCssNode *cssnode,
+ GString *string)
+{
+ const char *id;
+
+ id = gtk_css_node_get_id (cssnode);
+ if (id)
+ {
+ g_string_append (string, " id=");
+ g_string_append (string, id);
+ }
+}
+
+static void
+append_visible (GtkCssNode *cssnode,
+ GString *string)
+{
+ g_string_append_printf (string, " visible=%d", gtk_css_node_get_visible (cssnode));
+}
+
+static void
+append_state (GtkCssNode *cssnode,
+ GString *string)
+
+{
+ GtkStateFlags state;
+
+ state = gtk_css_node_get_state (cssnode);
+ if (state)
+ {
+ GFlagsClass *fclass;
+ gint i;
+ gboolean first = TRUE;
+
+ g_string_append (string, " state=");
+ fclass = g_type_class_ref (GTK_TYPE_STATE_FLAGS);
+ for (i = 0; i < fclass->n_values; i++)
+ {
+ if (state & fclass->values[i].value)
+ {
+ if (first)
+ first = FALSE;
+ else
+ g_string_append_c (string, '|');
+ g_string_append (string, fclass->values[i].value_nick);
+ }
+ }
+ g_type_class_unref (fclass);
+ }
+}
+
+static void
+append_classes (GtkCssNode *cssnode,
+ GString *string)
+{
+ const GQuark *classes;
+ guint n_classes;
+
+ classes = gtk_css_node_list_classes (cssnode, &n_classes);
+ if (n_classes > 0)
+ {
+ int i;
+
+ g_string_append (string, " classes=");
+ for (i = 0; i < n_classes; i++)
+ {
+ if (i > 0)
+ g_string_append_c (string, ',');
+ g_string_append (string, g_quark_to_string (classes[i]));
+ }
+ }
+}
+
+static gboolean
+gtk_css_node_has_initial_value (GtkCssNode *cssnode,
+ GtkCssStyleProperty *prop)
+{
+ GtkCssNode *parent_node;
+ GtkCssStyle *style, *parent_style;
+ GtkCssValue *value, *initial, *computed;
+ GtkCssProvider *provider;
+ gboolean is_initial;
+ guint id;
+
+ id = _gtk_css_style_property_get_id (prop);
+ style = gtk_css_node_get_style (cssnode);
+ value = gtk_css_style_get_value (style, id);
+
+ parent_node = gtk_css_node_get_parent (cssnode);
+ parent_style = parent_node ? gtk_css_node_get_style (parent_node) : NULL;
+ provider = gtk_css_node_get_style_provider (cssnode);
+
+ initial = _gtk_css_style_property_get_initial_value (prop);
+ computed = _gtk_css_value_compute (initial, id, provider, style, parent_style);
+
+ is_initial = _gtk_css_value_equal (value, computed);
+
+ _gtk_css_value_unref (computed);
+
+ return is_initial;
+}
+
+static void
+append_value (GtkCssNode *cssnode,
+ GtkCssStyleProperty *prop,
+ GString *string,
+ guint indent)
+{
+ GtkCssValue *value;
+ GtkCssStyle *style;
+ GtkCssSection *section;
+ const char *name;
+ guint id;
+
+ id = _gtk_css_style_property_get_id (prop);
+ name = _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop));
+ style = gtk_css_node_get_style (cssnode);
+ value = gtk_css_style_get_value (style, id);
+
+ g_string_append_printf (string, "%*s%s: ", indent, "", name);
+
+ _gtk_css_value_print (value, string);
+
+ section = gtk_css_style_get_section (style, id);
+ if (section)
+ {
+ g_string_append (string, " (");
+ _gtk_css_section_print (section, string);
+ g_string_append (string, ")");
+ }
+
+ g_string_append_c (string, '\n');
+}
+
+static void
+append_style (GtkCssNode *cssnode,
+ GtkStyleContextPrintFlags flags,
+ GString *string,
+ guint indent)
+{
+ int i;
+
+ if (!(flags & GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE))
+ return;
+
+ for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++)
+ {
+ GtkCssStyleProperty *prop;
+
+ prop = _gtk_css_style_property_lookup_by_id (i);
+
+ if ((flags & GTK_STYLE_CONTEXT_PRINT_SHOW_INITIAL) ||
+ !gtk_css_node_has_initial_value (cssnode, prop))
+ append_value (cssnode, prop, string, indent);
+ }
+}
+
+void
+gtk_css_node_print (GtkCssNode *cssnode,
+ GtkStyleContextPrintFlags flags,
+ GString *string,
+ guint indent)
+{
+ GtkCssNode *node;
+
+ g_string_append_printf (string, "%*s", indent, "");
+ if (gtk_css_node_get_name (cssnode))
+ g_string_append (string, gtk_css_node_get_name (cssnode));
+ else
+ g_string_append (string, g_type_name (gtk_css_node_get_widget_type (cssnode)));
+ append_id (cssnode, string);
+ append_visible (cssnode, string);
+ append_state (cssnode, string);
+ append_classes (cssnode, string);
+ g_string_append_c (string, '\n');
+
+ append_style (cssnode, flags, string, indent + 2);
+
+ if (flags & GTK_STYLE_CONTEXT_PRINT_RECURSE)
+ {
+ for (node = gtk_css_node_get_first_child (cssnode); node; node = gtk_css_node_get_next_sibling (node))
+ gtk_css_node_print (node, flags, string, indent + 2);
+ }
+}
corner_value_is_right_angle (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_BOTTOM_RIGHT_RADIUS)) &&
corner_value_is_right_angle (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_BORDER_BOTTOM_LEFT_RADIUS)));
}
+
+/**
+ * GtkStyleContextPrintFlags:
+ * @GTK_STYLE_CONTEXT_PRINT_RECURSE: Print the entire tree of
+ * CSS nodes starting at the style context's node
+ * @GTK_STYLE_CONTEXT_PRINT_SHOW_STYLE: Show the values of the
+ * CSS properties for each node
+ * @GTK_STYLE_CONTEXT_PRINT_SHOW_INITIAL: Show the values of the
+ * CSS properties even if they match the initial value. By default,
+ * values are only shown if they are different from the initial
+ * value.
+ *
+ * Flags that modify the behavior of gtk_style_context_to_string().
+ * New values may be added to this enumeration.
+ */
+
+/**
+ * gtk_style_context_to_string:
+ * @context: a #GtkStyleContext
+ * @flags: Flags that determine what to print
+ *
+ * Converts the style context into a string representation.
+ *
+ * The string representation always includes information about
+ * the name, state, id, visibility and style classes of the CSS
+ * node that is backing @context. Depending on the flags, more
+ * information may be included.
+ *
+ * This function is intended for testing and debugging of the
+ * CSS implementation in GTK+. There are no guarantees about
+ * the format of the returned string, it may change.
+ *
+ * Returns: a newly allocated string representing @context
+ *
+ * Since: 3.20
+ */
+char *
+gtk_style_context_to_string (GtkStyleContext *context,
+ GtkStyleContextPrintFlags flags)
+{
+ GString *string;
+
+ g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
+
+ string = g_string_new ("");
+
+ gtk_css_node_print (context->priv->cssnode, flags, string, 0);
+
+ return g_string_free (string, FALSE);
+}